`timescale 1ps / 1ps
module ctrl(
    input [31:0] ins,
    output [4:0] Rs,Rt,Rd,
    output [15:0] imm16,
    output [4:0] shf,
    output reg [3:0] ALUctr,
    output reg [2:0] Branch,
    output reg [1:0] Jump,
    output reg [1:0] RegWr,
    output reg RegDst,
    output reg ExtOp,
    output reg ALUsrc,
    output reg [1:0] MemWr,
    output reg MemtoReg,
    output reg ALUshf,
    output reg R31wr
);
reg [5:0] OP;
reg [5:0] func;
assign Rs = ins[25:21];
assign Rt = ins[20:16];
assign Rd = ins[15:11];
assign imm16 = ins[15:0];
assign shf = ins[10:6];

parameter R = 6'b000000;
parameter ADDI = 6'b001000,ADD = 6'b100000,ADDU = 6'b100001,ADDIU = 6'b001001;

parameter LW = 6'b100011, SW = 6'b101011,SB = 6'b101000;
parameter LB = 6'b100000, LBU = 6'b100100;

parameter SUB = 6'b100010, AND = 6'b100100,OR = 6'b100101;
parameter SUBU = 6'b100011;

parameter NOR = 6'b100111, XOR = 6'b100110;

parameter J = 6'b000010,JR = 6'b001000,JALR = 6'b001001,JAL = 6'b000011;

parameter SLLV = 6'b000100, SRLV = 6'b000110,SLL = 6'b000000,SRL = 6'b000010;
parameter SRA = 6'b000011,SRAV = 6'b000111;

parameter SLT = 6'b101010,SLTI = 6'b001010,SLTIU = 6'b001011,SLTU = 6'b101011;

parameter ANDI = 6'b001100,ORI = 6'b001101,XORI=6'b001110;

parameter BEQ = 6'b000100,BNE = 6'b000101,BGEZ = 6'b000001,BGTZ = 6'b000111,BLEZ=6'b000110,BLTZ=6'b000001;

parameter LUI = 6'b001111;

always @(*) begin
    OP = ins[31:26];
    func = ins[5:0];
    case (OP)
        R:begin
            Branch = 0;
			Jump = 0;
			RegDst = 1;
			ALUsrc = 0;	
			MemtoReg = 0;
			RegWr = 1;
			MemWr = 0;
			ExtOp = 0;
            ALUshf = 0;
            case (func)
                ADD:  ALUctr = 0;
                ADDU: ALUctr = 1;
                SUB:  ALUctr = 2;
                SUBU: ALUctr = 3;
                AND:  ALUctr = 4;
                OR :  ALUctr = 5; 
                SLT:  ALUctr = 6;
                SLTU: ALUctr = 7;
                NOR:  ALUctr = 8;
                XOR:  ALUctr = 9;
                SLLV: ALUctr = 10;
                SRLV: ALUctr = 11;
                SRAV: ALUctr = 13;
                SLL: begin ALUctr = 0; ALUshf = 1; end
                SRL: begin ALUctr = 1; ALUshf = 1; end
                JR : begin Jump = 2; R31wr = 0; end
                JALR:begin Jump = 2; R31wr = 1; end
                SRA: begin ALUctr = 2; ALUshf = 1;end
            endcase
        end
//DateMemory
        LW:begin
            Branch = 0;
            Jump = 0;
            
            RegDst = 0;
            RegWr = 1;
            
            MemWr = 0;
            MemtoReg = 1;

            ExtOp = 1;
            ALUsrc = 1; 
            ALUctr = 0;
            ALUshf = 0;
            
            R31wr = 0;
        end

        LB:begin
            Branch = 0;
            Jump = 0;
            
            RegDst = 0;
            RegWr = 2;
            
            MemWr = 0;
            MemtoReg = 1;

            ExtOp = 1;
            ALUsrc = 1; 
            ALUctr = 0;
            ALUshf = 0;
            
            R31wr = 0;
        end

        LBU:begin
            Branch = 0;
            Jump = 0;
            
            RegDst = 0;
            RegWr = 3;
            
            MemWr = 0;
            MemtoReg = 1;

            ExtOp = 1;
            ALUsrc = 1; 
            ALUctr = 0;
            ALUshf = 0;
            
            R31wr = 0;
        end

        SW:begin
            Branch = 0;
            Jump = 0;
            
            RegDst = 0;
            RegWr = 0;
            
            MemWr = 1;
            MemtoReg = 0;
            
            ExtOp = 1;
            ALUsrc = 1; 
            ALUctr = 0; 
            ALUshf = 0;

            R31wr = 0;
        end

        SB:begin
            Branch = 0;
            Jump = 0;
            
            RegDst = 0;
            RegWr = 0;
            
            MemWr = 2;
            MemtoReg = 0;
            
            ExtOp = 1;
            ALUsrc = 1; 
            ALUctr = 0; 
            ALUshf = 0;

            R31wr = 0;
        end



// I type
        ADDI:begin
            Branch = 0;
            Jump = 0;
            
            RegDst = 0;
            RegWr = 1;
            
            MemWr = 1;
            MemtoReg = 0;
            
            ExtOp = 1;
            ALUsrc = 1; 
            ALUctr = 0;
            ALUshf = 0;

            R31wr = 0;
        end

        ADDIU:begin
            Branch = 0;
            Jump = 0;
            
            RegDst = 0;
            RegWr = 1;
            
            MemWr = 1;
            MemtoReg = 0;
            
            ExtOp = 1;
            ALUsrc = 1; 
            ALUctr = 1;
            ALUshf = 0;

            R31wr = 0;
        end

        ANDI:begin
            Branch = 0;
            Jump = 0;
            
            RegDst = 0;
            RegWr = 1;
            
            MemWr = 1;
            MemtoReg = 0;
            
            ExtOp = 0;
            ALUsrc = 1; 
            ALUctr = 4;
            ALUshf = 0;

            R31wr = 0;
        end

        ORI:begin
            Branch = 0;
            Jump = 0;
            
            RegDst = 0;
            RegWr = 1;
            
            MemWr = 1;
            MemtoReg = 0;
            
            ExtOp = 0;
            ALUsrc = 1; 
            ALUctr = 5;
            ALUshf = 0;

            R31wr = 0;
        end

        XORI:begin
            Branch = 0;
            Jump = 0;
            
            RegDst = 0;
            RegWr = 1;
            
            MemWr = 1;
            MemtoReg = 0;
            
            ExtOp = 0;
            ALUsrc = 1; 
            ALUctr = 9;
            ALUshf = 0;

            R31wr = 0;
        end

        SLTI:begin
            Branch = 0;
            Jump = 0;
            
            RegDst = 0;
            RegWr = 1;
            
            MemWr = 1;
            MemtoReg = 0;
            
            ExtOp = 1;
            ALUsrc = 1; 
            ALUctr = 6;
            ALUshf = 0;

            R31wr = 0;
        end

        SLTIU:begin
            Branch = 0;
            Jump = 0;
            
            RegDst = 0;
            RegWr = 1;
            
            MemWr = 1;
            MemtoReg = 0;
            
            ExtOp = 1;
            ALUsrc = 1; 
            ALUctr = 7;
            ALUshf = 0;

            R31wr = 0;
        end
// #Branch       
			BEQ:begin
            Branch = 1;
            Jump = 0;
            
            RegDst = 0;
            RegWr = 0;
            
            MemWr = 0;
            MemtoReg = 0;
            
            ExtOp = 1;
            ALUsrc = 0; 
            ALUctr = 2; 
            ALUshf = 0;

            R31wr = 0;
        end

        BNE:begin
            Branch = 2;
            Jump = 0;
            
            RegDst = 0;
            RegWr = 0;
            
            MemWr = 0;
            MemtoReg = 0;
            
            ExtOp = 1;
            ALUsrc = 0; 
            ALUctr = 2; 
            ALUshf = 0;

            R31wr = 0;
        end


        BGTZ:begin
            Branch = 4;
            Jump = 0;
            
            RegDst = 0;
            RegWr = 0;
            
            MemWr = 0;
            MemtoReg = 0;
            
            ExtOp = 1;
            ALUsrc = 0; 
            ALUctr = 2; 
            ALUshf = 0;
            
            R31wr = 0;
        end

        BLEZ:begin
            Branch = 5;
            Jump = 0;
            
            RegDst = 0;
            RegWr = 0;
            
            MemWr = 0;
            MemtoReg = 0;
            
            ExtOp = 1;
            ALUsrc = 0; 
            ALUctr = 2; 
            ALUshf = 0;

            R31wr = 0;
        end

        BGEZ:begin
            if(Rt == 1)
                Branch = 3;
            Jump = 0;
            
            RegDst = 0;
            RegWr = 0;
            
            MemWr = 0;
            MemtoReg = 0;
            
            ExtOp = 1;
            ALUsrc = 0; 
            ALUctr = 2; 
            ALUshf = 0;

            R31wr = 0;
        end

        BLTZ:begin
            if(Rt == 0)
                Branch = 6;
            Jump = 0;
            
            RegDst = 0;
            RegWr = 0;
            
            MemWr = 0;
            MemtoReg = 0;
            
            ExtOp = 1;
            ALUsrc = 0; 
            ALUctr = 2; 
            ALUshf = 0;

            R31wr = 0;
        end
// J
        J:begin
            Branch = 0;
            Jump = 1;
            
            RegDst = 0;
            RegWr = 0;
            
            MemWr = 0;
            MemtoReg = 0;
            
            ExtOp = 1;
            ALUsrc = 0; 
            ALUctr = 0; 
            ALUshf = 0;

            R31wr = 0;
        end

        JAL:begin
            Branch = 0;
            Jump = 1;
            
            RegDst = 0;
            RegWr = 0;
            
            MemWr = 0;
            MemtoReg = 0;
            
            ExtOp = 1;
            ALUsrc = 0; 
            ALUctr = 0; 
            ALUshf = 0;

            R31wr = 1;
        end

//   LUI
        LUI:begin
            Branch = 0;
            Jump = 0;
            
            RegDst = 0;
            RegWr = 1;
            
            MemWr = 0;
            MemtoReg = 0;
            
            ExtOp = 0;
            ALUsrc = 1; 
            ALUctr = 12;
            ALUshf = 0;

            R31wr = 0;
        end

    endcase 


end

endmodule
